﻿using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.IO;
using UnityEngine;
using System;
using Newtonsoft.Json;
using Kylin;


public class GUIDependencyCollect
{

    private class UIDependencyItem
    {
        public string prefabPath;
        public List<string> atlasPath = new List<string>();

        public void Push(string ap)
        {
            if (string.IsNullOrEmpty(ap)) return;

            bool exist = false;
            for (int i = 0; i < atlasPath.Count; ++i)
            {
                if (atlasPath[i].Equals(ap))
                {
                    exist = true;
                }
            }

            if (!exist)
            {
                atlasPath.Add(ap);
            }
        }
    }


    private class UIDependencyRoot
    {
        public string rootPath = "dependencies";
        public List<UIDependencyItem> uiDependencyItemList = new List<UIDependencyItem>();

        public void PrepareAdd(UIDependencyItem item)
        {
            uiDependencyItemList.Add(item);
        }

        public void Push(string ownedPrefab, string atlasPath)
        {
            for (int i = 0; i < uiDependencyItemList.Count; ++i)
            {
                if (ownedPrefab.Equals(uiDependencyItemList[i].prefabPath))
                {
                    uiDependencyItemList[i].Push(atlasPath);
                }
            }
        }
    }

    public static readonly string AtlasPath = ResourcePath.HotFixFolderName + "/Atlas";
    public static readonly string UIPrefabPath = ResourcePath.HotFixFolderName + "/Prefab/UI";
    public static readonly string GUIDependencyFilePathInEditor = "Resources/" + ResourcePath.HotFixFolderName + "/GUIDependency";

    [MenuItem("Kylin/GUITool/Collect GUI Dependency", false, 0)]
	public static void CollectGUIDependency()
	{
        List<string> atlasList = CollectAtlas();
        List<string> prefabList = CollectPrefab();

        for (int i = 0; i < prefabList.Count; ++i)
        {
            for (int j = 0; j < atlasList.Count; ++j)
            {
                if (CheckIfPrefabDependOnAtlas(prefabList[i], atlasList[j]))
                {
                    string prefabPath = prefabList[i].Replace("Assets/Resources/" + ResourcePath.HotFixFolderName + "/", "");
                    string atlasPath = atlasList[j].Replace("Assets/Resources/" + ResourcePath.HotFixFolderName + "/", "");
                    Collect(prefabPath, atlasPath);
                }
            }
        }

        // 列表已经全部收集完毕，最后处理一下重复的
        PostProcess();
	}

    private static List<string> prefabAtlasList = new List<string>();

    private static void Collect(string prefabPath, string atlasPath)
    {
        prefabAtlasList.Add(prefabPath);
        prefabAtlasList.Add(atlasPath);
    }


    private static List<Dictionary<string, List<string>>> allDependencies = new List<Dictionary<string, List<string>>>();
    private static void PostProcess()
    {
        //萃取所有的key
        Dictionary<string, string> prefabKeys = new Dictionary<string, string>();
        for (int i = 0; i < prefabAtlasList.Count; i += 2)
        {
            if (prefabKeys.ContainsKey(prefabAtlasList[i])) continue;

            prefabKeys.Add(prefabAtlasList[i], prefabAtlasList[i]);
        }

        UIDependencyRoot root = new UIDependencyRoot();
        foreach(KeyValuePair<string, string> keyValuePair in prefabKeys)
        {
            UIDependencyItem item = new UIDependencyItem();
            item.prefabPath = keyValuePair.Key;
            root.PrepareAdd(item);
        }


        for (int i = 0; i < prefabAtlasList.Count; i += 2)
        {
            root.Push(prefabAtlasList[i], prefabAtlasList[i + 1]);
        }

        string result = JsonConvert.SerializeObject(root);
        string filePath = Application.dataPath + "/" + GUIDependencyFilePathInEditor + "/" + "GUIdependency.txt";
        StreamWriter streamWriter = File.CreateText(filePath);
        streamWriter.Write(result);
        streamWriter.Flush();
        streamWriter.Close();
        streamWriter.Dispose();
    }

    private static bool CheckIfPrefabDependOnAtlas(string prefabPath, string atlasPath)
    {
        string[] prefabDependencies = AssetDatabase.GetDependencies(prefabPath);
        prefabDependencies = RemovePrefab(prefabDependencies);
        string[] atlasDependencies = AssetDatabase.GetDependencies(atlasPath);
        atlasDependencies = RemoveAtlas(atlasDependencies);

        for (int i = 0; i < prefabDependencies.Length; ++i)
        {
            for (int j = 0; j < atlasDependencies.Length; ++j)
            {
                if (prefabDependencies[i].Equals(atlasDependencies[j]))
                {
                    return true;
                }
            }
        }

        return false;
    }

    private static string[] RemovePrefab(string[] array)
    {
        List<string> result = new List<string>();

        for (int i = 0; i < array.Length; ++i)
        {
            if (Path.GetExtension(array[i]).Equals(".prefab")) continue;
            result.Add(array[i]);
        }

        return result.ToArray();
    }

    private static string[] RemoveAtlas(string[] array)
    {
        List<string> result = new List<string>();

        for (int i = 0; i < array.Length; ++i)
        {
            if (Path.GetExtension(array[i]).Equals(".spriteatlas")) continue;
            result.Add(array[i]);
        }

        return result.ToArray();
    }

    private static List<string> CollectAtlas()
    {
        string path = Application.dataPath + "/Resources/" + AtlasPath;

        List<string> allFiles = FileUtils.GetAllFileInDir(path);

        List<string> spriteAtlasFileList = new List<string>();
        for (int i = 0; i < allFiles.Count; ++i)
        {
            string filePath = allFiles[i].Replace('\\', '/');

            if (Path.GetExtension(filePath).Equals(".spriteatlas"))
            {
                string shortPath = filePath.Replace(Application.dataPath, "");
                shortPath = "Assets" + shortPath;
                spriteAtlasFileList.Add(shortPath);
            }
        }


        return spriteAtlasFileList;
    }

    private static List<string> CollectPrefab()
    {
        string path = Application.dataPath + "/Resources/" + UIPrefabPath;

        List<string> allFiles = FileUtils.GetAllFileInDir(path);

        List<string> uiPrefabFileList = new List<string>();
        for (int i = 0; i < allFiles.Count; ++i)
        {
            string filePath = allFiles[i].Replace('\\', '/');

            if (Path.GetExtension(filePath).Equals(".prefab"))
            {
                string shortPath = filePath.Replace(Application.dataPath, "");
                shortPath = "Assets" + shortPath;
                uiPrefabFileList.Add(shortPath);
            }
        }


        return uiPrefabFileList;
    }
}
